﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using VideoRentalShop.Controller;
using VideoRentalShop.Model;
using System.ComponentModel;

namespace VideoRentalShop.View.Windows.MovieList
{
    /// <summary>
    /// Logika interakcji dla klasy EditPanel.xaml
    /// </summary>
    public partial class EditPanel : UserControl
    {
        private VideoRentalShopController _controller = VideoRentalShopController.Instance;
        private Movie _selectedItem;
        private System.Windows.Forms.OpenFileDialog _fileDialog;
        private string _picturePath;
        private bool _pictureCopied = false;


        public EditPanel()
        {
            InitializeComponent();

            _fileDialog = new System.Windows.Forms.OpenFileDialog();
            _fileDialog.Filter = "Image files (*.jpeg, *.jpg, *.png, *.bmp, *.gif)|*.jpeg;*.jpg;*.png;*.bmp;*.gif";
            _fileDialog.CheckFileExists = true;
            _fileDialog.CheckPathExists = true;
            _fileDialog.Multiselect = false;
            _fileDialog.FileOk += new CancelEventHandler(PictureFileChoosen);
            
            foreach (var genre in _controller.Data.Genre.GetAll().OrderBy(x => x.Title))
            {
                lstGenre.Items.Add(new CheckBox { Content = genre.Title, Tag = genre.Id });
            }
        }


        public bool Add()
        {
            var completed = false;
            var item = new Movie();
            if (CopyData(item))
            {
                completed = _controller.Data.Movie.Add(item);

                if (completed)
                {
                    _controller.ShowMessage("Pomyślnie dodano film.", "Powodzenie", MessageType.Error);
                }
                else
                {
                    _controller.ShowMessage("Podczas dodawania danych o filmie wystąpił błąd.\nSprawdź, czy wszystkie dane zostały podane i są poprawne.", "Błąd", MessageType.Error);
                }
            }

            return completed;
        }

        public bool Edit()
        {
            var completed = false;
            if (CopyData(_selectedItem, true))
            {
                completed = _controller.Data.Movie.Edit(_selectedItem);

                if (completed)
                {
                    _controller.ShowMessage("Pomyślnie zmodyfikowano dane o filmie.", "Powodzenie", MessageType.Error);
                }
                else
                {
                    _controller.ShowMessage("Podczas edycji danych o filmie wystąpił błąd.\nSprawdź, czy wszystkie dane zostały podane i są poprawne.", "Błąd", MessageType.Error);
                }
            }

            return completed;
        }


        private bool CopyData(Movie item, bool hasData = false)
        {
            var copy = (Movie)null;
            if (hasData)
            {
                copy = new Movie();
                CopyItem(copy, item);
            }

            item.Title = txtTitle.Text.Trim();
            item.OriginalTitle = txtOriginalTitle.Text.Trim();
            item.Director = txtDirector.Text.Trim();
            item.Description = new TextRange(txtDescription.Document.ContentStart, txtDescription.Document.ContentEnd).Text.Trim();
            item.OriginCountry = txtCountry.Text.Trim();
            item.ReleaseDate = dtpReleaseDate.SelectedDate;
            if (nudQunatity.Value.HasValue)
            {
                item.Quantity = nudQunatity.Value.Value;
            }
            else
            {
                _controller.ShowMessage("Wymagane jest podanie ilości kopii.", "Uzupełnij dane", MessageType.Error);
                return false;
            }
            if (nudAvaiable.Value.HasValue)
            {
                item.Avaiable = nudAvaiable.Value.Value;
            }
            else
            {
                _controller.ShowMessage("Wymagane jest podanie ilości dostępnych kopii.", "Uzupełnij dane", MessageType.Error);
                return false;
            }

            AddMinAge(item);
            AddPicture(item);
            AddGenres(item);

            var valid = CheckData(item);
            if (valid)
            {
                valid = _controller.Data.Movie.IsValid(item);
            }

            if (hasData && !valid)
            {
                CopyItem(item, copy);
            }

            return valid;
        }

        private void CopyItem(Movie to, Movie from)
        {
            to.Title = from.Title;
            to.OriginalTitle = from.OriginalTitle;
            to.Director = from.Director;
            to.Description = from.Description;
            to.OriginCountry = from.OriginCountry;
            to.ReleaseDate = from.ReleaseDate;
            to.Quantity = from.Quantity;
            to.Avaiable = from.Avaiable;
            to.MinAge = from.MinAge;
            to.PictureName = from.PictureName;

            to.Genres.Clear();
            foreach (var genre in from.Genres)
            {
                to.Genres.Add(genre);
            }
        }

        private bool CheckData(Movie movie)
        {
            if (!IsAgeChoosen())
            {
                _controller.ShowMessage("Musisz podać kategorię wiekową dla filmu.", "Uzupełnij dane", MessageType.Error);
                return false;
            }

            if (movie.Avaiable > movie.Quantity)
            {
                _controller.ShowMessage("Ilość dostępnych kopii musi być mniejsza od całkowitej ilości kopii.", "Błąd", MessageType.Error);
                return false;
            }

            if (movie.Genres.Count == 0)
            {
                _controller.ShowMessage("Wymagane jest przypisanie filmu do co najmniej jednego gatunku.", "Uzupełnij dane", MessageType.Error);
                return false;
            }

            if (string.IsNullOrWhiteSpace(movie.Title))
            {
                _controller.ShowMessage("Wymagane jest podanie tytułu filmu.", "Uzupełnij dane", MessageType.Error);
                return false;
            }
            if (movie.Title.Length > 100 || (!string.IsNullOrWhiteSpace(movie.OriginalTitle) && movie.OriginalTitle.Length > 100))
            {
                _controller.ShowMessage("Podana nazwa filmu jest zbyt długa (max 100 znaków).", "Popraw dane", MessageType.Error);
                return false;
            }
            if (!string.IsNullOrWhiteSpace(movie.OriginCountry) && movie.OriginCountry.Length > 30)
            {
                _controller.ShowMessage("Podana nazwa państwa jest zbyt długa (max 30 znaków).", "Popraw dane", MessageType.Error);
                return false;
            }
            if (!string.IsNullOrWhiteSpace(movie.Director) && movie.Director.Length > 60)
            {
                _controller.ShowMessage("Podane imię i nazwisko reżysera są zbyt długie (max 60 znaków).", "Popraw dane", MessageType.Error);
                return false;
            }
            if (!string.IsNullOrWhiteSpace(movie.Description) && movie.Description.Length > 1000)
            {
                _controller.ShowMessage("Podany opis filmu jest zbyt długi (max 1000 znaków).", "Popraw dane", MessageType.Error);
                return false;
            }

            return true;
        }

        private int AddGenres(Movie movie)
        {
            movie.Genres.Clear();
            var count = 0;
            foreach (var item in lstGenre.Items)
            {
                var chb = item as CheckBox;
                if (chb.IsChecked == true)
                {
                    var details = new GenreDetails();
                    details.GenreId = (long)chb.Tag;
                    details.Movie = movie;

                    movie.Genres.Add(details);
                    ++count;
                }
            }

            return count;
        }

        private bool IsAgeChoosen()
        {
            return optAge0.IsChecked == true || optAge1.IsChecked == true || optAge2.IsChecked == true || optAge3.IsChecked == true || optAge4.IsChecked == true;
        }
        
        private void AddMinAge(Movie movie)
        {
            movie.MinAge = 0;
            if (optAge1.IsChecked == true) { movie.MinAge = 7; }
            else if (optAge2.IsChecked == true) { movie.MinAge = 12; }
            else if (optAge3.IsChecked == true) { movie.MinAge = 16; }
            else if (optAge4.IsChecked == true) { movie.MinAge = 18; }
        }

        private bool AddPicture(Movie movie)
        {
            if (_pictureCopied)
            {
                movie.PictureName = _picturePath;
            }
            else
            {
                if (_picturePath == null)
                {
                    return false;
                }

                var picture = _controller.SavePicture(_picturePath);
                movie.PictureName = picture;
            }

            return true;
        }

        private void btnChoosePicture_Click(object sender, RoutedEventArgs e)
        {
            _fileDialog.ShowDialog();
        }

        private void PictureFileChoosen(object sender, CancelEventArgs e)
        {
            _pictureCopied = false;
            _picturePath = _fileDialog.FileName;
            var idx = _picturePath.LastIndexOf('\\');
            var name = _picturePath.Substring(idx + 1);
            lblPictureName.Content = name;
        }

        public void Clear()
        {
            txtTitle.Text = string.Empty;
            txtOriginalTitle.Text = string.Empty;
            txtCountry.Text = string.Empty;
            txtDirector.Text = string.Empty;
            txtDescription.Document.Blocks.Clear();
            nudQunatity.Value = 1;
            nudAvaiable.Value = 1;
            dtpReleaseDate.SelectedDate = null;
            lblPictureName.Content = "(brak)";
            _picturePath = null;
            _pictureCopied = false;

            foreach (var genre in lstGenre.Items)
            {
                var chb = genre as CheckBox;
                chb.IsChecked = false;
            }

            optAge0.IsChecked = false;
            optAge1.IsChecked = false;
            optAge2.IsChecked = false;
            optAge3.IsChecked = false;
            optAge4.IsChecked = false;
        }

        public void LoadItem(Movie item = null)
        {
            _selectedItem = item;
            if (item == null)
            {
                Clear();
            }
            else
            {
                txtTitle.Text = item.Title;
                txtOriginalTitle.Text = item.OriginalTitle ?? string.Empty;
                txtCountry.Text = item.OriginCountry ?? string.Empty;
                txtDirector.Text = item.Director ?? string.Empty;
                txtDescription.Document.Blocks.Clear();
                txtDescription.AppendText(item.Description ?? string.Empty);
                nudQunatity.Value = item.Quantity;
                nudAvaiable.Value = item.Avaiable;
                dtpReleaseDate.SelectedDate = item.ReleaseDate;
                lblPictureName.Content = item.PictureName ?? "(brak)";
                _picturePath = item.PictureName;
                _pictureCopied = true;

                foreach (var genre in lstGenre.Items)
                {
                    var chb = genre as CheckBox;
                    var idx = (long)chb.Tag;
                    var count = item.Genres.Where(x => x.GenreId == idx).Count();
                    chb.IsChecked = count > 0;
                }

                optAge0.IsChecked = item.MinAge == 0;
                optAge1.IsChecked = item.MinAge == 7;
                optAge2.IsChecked = item.MinAge == 12;
                optAge3.IsChecked = item.MinAge == 16;
                optAge4.IsChecked = item.MinAge == 18;
            }
        }

        private void nudQunatity_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            if (nudAvaiable != null)
            {
                nudAvaiable.Maximum = nudQunatity.Value;

                if (nudAvaiable.Value > nudAvaiable.Maximum)
                {
                    nudAvaiable.Value = nudAvaiable.Maximum;
                }
            }
        }


    }
}
